# encoding: utf-8

def get_scope_multiplier(scope, card_type=None):
    result = 1.
    if scope in ["同学校", "同学年"]:
        result = 1.0*5/9
    if scope == "自身":
        result = 1.0/3
    if scope in ["高坂穗乃果", "上原步梦"]:
        result = 0.35
    if scope == "同类型":
        if not card_type:
            result = 0.5
        elif card_type == "gd" or card_type == "sk":
            result = 0.35
        elif card_type == "sp":
            result = 0.8
        elif card_type == "vo":
            result = 0.5
    return result

class Card(object):
    def __init__(self):
        self.name = ""
        self.names = ""
        self.ap = 0
        self.st = 0
        self.te = 0
        self.slot = 3
        self.card_type = "vo"
        self.color = "黄"
        self.passive_ap = 0
        self.passive_st = 0
        self.passive_te = 0
        self.passive_scope = ""
        self.actives = []
        self.skills = []
        self.skill_note = 0
        self.skill_trigger_rate = 1.
        self.skill_scope = ""
        self.special_score = ""
        self.debug = {
            "power_by_level": {}
        }

    def is_muse(self):
        if self.name[-1] in ["果", "绘", "鸟", "海", "凛", "姬", "希", "花", "妮"]:
            return True
        return False

    def is_aqours(self):
        if self.name[-1] in ["千", "梨", "南", "黛", "曜", "善", "丸", "鞠", "露"]:
            return True
        return False

    def is_nigigasaki(self):
        if self.name[-1] in ["步", "霞", "雫", "林", "爱", "彼", "菜", "艾", "璃", "栞", "米", "钟"]:
            return True
        return False

    def is_cyaron(self):
        if self.name[-1] in ["千", "曜", "露"]:
            return True
        return False

    def is_guilty_kiss(self):
        if self.name[-1] in ["梨", "善", "鞠"]:
            return True
        return False

    def calculate(self, team, song):
        active_1_scope_multiplier = get_scope_multiplier(self.passive_scope, self.card_type)
        self.final_ap = self.ap * team.kizuna_multiplier * team.raw_ap_multiplier
        self.final_ap += team.accesscory_ap
        self.final_ap *= team.accesscory_active_ap
        self.attack = self.final_ap + (self.passive_ap + .02 * (self.slot - 3)) * team.total_raw_ap * active_1_scope_multiplier
        self.attack *= team.same_attribute_multiplier

        self.final_st = self.st * team.kizuna_multiplier
        self.final_st += team.accesscory_st
        self.final_st += self.passive_st * self.st
        self.final_st *= team.same_attribute_multiplier

        self.real_te = self.te * team.kizuna_multiplier * team.raw_te_multiplier
        self.real_te += team.accesscory_te
        self.real_te += self.passive_te * self.te
        self.real_te *= team.same_attribute_multiplier
        self.critical_rate = 0.00003 * self.real_te + team.kizuna_critical_rate
        self.critical_rate += 0.15 if self.is_critical_card() else 0
        self.critical_rate = min(self.critical_rate, 1)

        self.teammate_raw_te = team.teammate_card_te * team.kizuna_multiplier
        self.teammate_real_te = self.teammate_raw_te * team.raw_te_multiplier
        self.teammate_real_te += team.accesscory_te
        self.teammate_real_te *= team.same_attribute_multiplier
        self.teammate_critical_rate = 0.00003 * self.teammate_real_te + team.kizuna_critical_rate

        self.magical = 0 # 突破上限得分
        self.score_limit = team.score_limit
        self.teammate_crit_bonus = self.passive_te * self.teammate_raw_te * team.same_attribute_multiplier * 0.00003
        self.active_2_support_average = 0. # 个2辅助能力
        self.active_2_support_max = 0.
        self.active_2_support_magical = 0.
        self.active_2_support_magical_same_attribute = 0.
        # 注：考虑到血线影响部分饰品效果未使用0.3
        self.heal_main = 0.25 * self.final_st * team.same_attribute_multiplier / team.total_notes
        self.heal_swap_one_time = 0.25 * self.final_st * team.same_attribute_multiplier / team.total_notes
        self.heal_swap = 0.
        self.heal_back = 0.25 * self.final_st / team.total_notes
        active_2_scope_multiplier = get_scope_multiplier(self.actives[0]["scope"], self.card_type)
        self.calculate_type(team)
        for active in self.actives:
            self.calculate_skill(active, team, song, scope_multiplier=active_2_scope_multiplier, trigger_rate=self.actives[0]["trigger_rate"])
        self.teammate_crit_bonus = min(1 - self.teammate_critical_rate, self.teammate_crit_bonus)
        skill_scope_multiplier = get_scope_multiplier(self.skill_scope, self.card_type)
        for skill in self.skills:
            self.calculate_skill(skill, team, song, is_skill=True, scope_multiplier=skill_scope_multiplier, trigger_rate=self.skill_trigger_rate)
        self.teammate_crit_bonus = min(1 - self.teammate_critical_rate, self.teammate_crit_bonus)

        # 计算点击分
        self.scoring = 0
        self.teammate_crit_scoring = 0
        for ap in team.appeal_multipliers.keys():
            critical_score = min(self.score_limit, team.critical_multiplier * ap * self.attack)
            self.scoring += team.appeal_multipliers[ap] * self.critical_rate * critical_score
            wonderful_score = min(self.score_limit, ap * self.attack)
            self.scoring += team.appeal_multipliers[ap] * (1 - self.critical_rate) * wonderful_score
            self.teammate_crit_scoring += team.appeal_multipliers[ap] * self.teammate_crit_bonus * (critical_score - wonderful_score)

        # 上+假设队友一张非暴击卡，上级假设半张
        if team.difficulty == "上级":
            self.teammate_crit_scoring /= 2
        self.average_note = self.scoring +self.teammate_crit_scoring + self.magical

        # 超限不适合环境，考虑后排少一个爆分的因素
        if self.score_limit > 140000 and team.difficulty == "上级" and self.average_note > 130000:
            self.average_note -= 2000

        # 计算后排辅助能力
        if team.level == "mid-high":
            self.calculate_support(team)

    def is_critical_card(self):
        if self.te > self.ap and self.te > self.st:
            return True
        return False

    def get_expert_value(self, power):
        result = 0.
        if power >= 102:
            result = 1 + (power - 100) * 0.05
        elif power >= 97:
            result = 0.7 + (power - 95) * 0.06
        elif power >= 92:
            result = 0.4 + (power - 90) * 0.06
        elif power >= 87:
            result = 0.2 + (power - 85) * 0.04
        elif power >= 82:
            result = 0.1 + (power - 80) * 0.02
        return result

    def get_advanced_value(self, power):
        result = 0.
        if power >= 109:
            result = 1 + (power - 109) * 0.07
        elif power >= 105:
            result = 0.7 + (power - 105) * 0.07
        elif power >= 101:
            result = 0.4 + (power - 101) * 0.07
        elif power >= 98:
            result = 0.1 + (power - 98) * 0.07
        return result

    def get_main_healer_value(self):
        power = self.get_heal_main()
        result = 0.
        if power >= 90:
            result = 1.5 + (power - 90) * 0.035
        elif power >= 80:
            result = 1.15 + (power - 80) * 0.035
        elif power >= 70:
            result = 0.8 + (power - 70) * 0.035
        elif power >= 60:
            result = 0.4 + (power - 60) * 0.04
        elif power >= 50:
            result = 0.1 + (power - 50) * 0.03
        return result

    def get_swap_healer_value(self):
        power = self.get_heal_swap()
        result = 0.
        if power >= 70:
            result = 0.2 + (power - 70) * 0.005
        elif power >= 60:
            result = 0.15 + (power - 60) * 0.005
        elif power >= 50:
            result = 0.1 + (power - 50) * 0.005
        return result

    def get_back_healer_value(self):
        if self.name == "兔子曜":
            return 0.2
        heal_back = (self.heal["上级"]["back"] + self.heal["上级+"]["back"]) / 2
        power = heal_back ** 0.5
        result = 0.
        if power >= 15:
            result = 0.3 + (power - 15) * 0.05
        elif power >= 13:
            result = 0.2 + (power - 13) * 0.05
        elif power >= 11:
            result = 0.1 + (power - 11) * 0.05
        return result

    def get_value(self):
        # 上+
        self.expert_score = 0.4 * self.get_expert_value(int(self.power["上级+"]["average"] / 2500))
        self.expert_score += 0.25 * self.get_expert_value(int(self.power["上级+"]["mid-high"] / 2500) - 10)
        self.expert_score += 0.2 * self.get_expert_value(int(self.power["上级+"]["very-high"] / 2500) - 20)

        # 上级
        self.advanced_score = 0.4 * self.get_advanced_value(int(self.power["上级"]["average"] / 1300))
        self.advanced_score += 0.25 * self.get_advanced_value(int(self.power["上级"]["very-high"] / 1300) - 3)
        self.advanced_score += 0.2 * self.get_advanced_value(int(self.power["上级"]["very-high"] / 1300) - 5)
        #self.advanced_score *= 0.7

        # 奶盾
        self.main_healer_score = self.get_main_healer_value()
        self.swap_healer_score = self.get_swap_healer_value()
        self.back_healer_score = self.get_back_healer_value()

        if len(self.skills) == 1 and self.skills[0]["type"] == "快充":
            self.advanced_score *= (1 + 1.5 * self.skills[0]["effect"])
            self.expert_score *= (1 + 0.75 * self.skills[0]["effect"])
        if len(self.skills) == 1 and self.skills[0]["type"] == "慢充":
            self.advanced_score *= (1 + 0.05 * self.skills[0]["effect"] * self.skill_notes)
            self.expert_score *= (1 + 0.025 * self.skills[0]["effect"])
        if self.name in ["p鸟", "p鞠", "p林", "3善"]:
            self.advanced_score *= 1.05
            self.expert_score *= 1.02

        return self.expert_score + self.advanced_score + self.main_healer_score + self.swap_healer_score + self.back_healer_score

    def get_scoring(self, global_stat):
        # 上级和上+输出
        self.scores = {}
        self.score_fix = {}
        self.scores["上级输出"] = max((self.power["上级"]["average"] - 77000) / 780, 0)
        for pos in [1, 2, 4]:
            self.scores["上级输出"] += 0.2 * (self.power["上级"]["average"] - global_stat["damage_sorted"]["上级"][self.color][pos]) / 780
        damage_advplus = 0.8 * self.power["上级+"]["average"] + 0.2 * self.power["无上限"]["average"]
        self.scores["上级+输出"] = max((damage_advplus - 62500) / 2500, 0)
        for pos in [2, 4, 9]:
            self.scores["上级+输出"] += 0.1 * (self.power["上级+"]["average"] - global_stat["damage_sorted"]["上级+"][self.color][pos]) / 2500
        # 一些调整计算
        if len(self.skills) == 1 and self.skills[0]["type"] == "快充":
            self.scores["上级输出"] += 50 * self.skills[0]["effect"]
            self.scores["上级+输出"] += 30 * self.skills[0]["effect"]
        if len(self.skills) == 1 and self.skills[0]["type"] == "慢充":
            self.scores["上级输出"] += 1.5 * self.skills[0]["effect"] * self.skill_notes
            self.scores["上级+输出"] += 1 * self.skills[0]["effect"]
        if self.name in ["p鸟", "p鞠", "p林", "3善"]:
            self.scores["上级输出"] += 2
            self.scores["上级+输出"] += 1
        #else:
        #    self.scores["上级输出"] -= 2.5
        #    self.scores["上级+输出"] -= 1.5
        if self.name[-1] in ["米", "钟"]:
            self.scores["上级输出"] -= 1
            self.scores["上级+输出"] -= 2
        # 考虑到有超限时，需要2个人打更高按键分更累的问题
        if self.actives[0]["type"] == "超限":
            self.scores["上级输出"] -= 2
            self.scores["上级+输出"] -= 2
        # 上+环境计算
        if self.color == "粉":
            # new romantic sailers
            if self.is_guilty_kiss():
                self.scores["上级+输出"] += 1
        if self.color == "绿":
            # 青空、大扑棱蛾子
            if self.is_aqours():
                self.scores["上级+输出"] += 3
            else:
                self.scores["上级+输出"] -= 1
        if self.color == "黄":
            # 主要是君辉，次要evergreen
            if self.card_type == "sk":
                self.scores["上级+输出"] += 2
            else:
                self.scores["上级+输出"] -= 1
        if self.color == "红":
            # 虹色
            if self.card_type == "sk":
                self.scores["上级+输出"] += 1
            # braveheart coaster
            if self.is_cyaron():
                self.scores["上级+输出"] += 1
        if self.color == "紫":
            # no brand girl
            if self.is_muse() and self.card_type == "vo":
                self.scores["上级+输出"] += 1
            # 女主角
            if self.is_nigigasaki() and self.skills[0]["type"] == "快充":
                self.scores["上级+输出"] += 1

        self.scores["上级输出"] = max(self.scores["上级输出"], 0)
        self.scores["上级+输出"] = max(self.scores["上级+输出"], 0)
        
        # 辅助能力
        support_all = self.get_support_all()
        support_same_attribute = self.get_support_same_attribute()
        self.scores["通用后排辅助"] = max((support_all - 0.007) * 1000, 0)
        self.scores["同属性后排辅助"] = max((support_same_attribute - 0.02) * 800, 0)
        for pos in [2, 5]:
            self.scores["通用后排辅助"] += 0.1 * (support_all - global_stat["support"]["通用"][pos]) * 1000
        if support_all < global_stat["support"]["通用"][10]:
            self.scores["通用后排辅助"] += 0.2 * (support_all - global_stat["support"]["通用"][10]) * 1000
        for pos in [2, 5]:
            self.scores["同属性后排辅助"] += 0.1 * (support_same_attribute - global_stat["support"][self.color][pos]) * 800
        if support_same_attribute < global_stat["support"][self.color][7]:
            self.scores["同属性后排辅助"] += 0.2 * (support_same_attribute - global_stat["support"][self.color][10]) * 800
        self.scores["通用后排辅助"] = max(self.scores["通用后排辅助"], 0)
        self.scores["同属性后排辅助"] = max(self.scores["同属性后排辅助"], 0)

        # 奶盾能力
        self.scores["前排奶盾"] = self.get_heal_main()
        self.scores["前排奶盾"] = max(self.scores["前排奶盾"], 0)
        
        for pos in [0, 1]:
            self.scores["前排奶盾"] += 0.1 * (self.get_heal_main() - global_stat["heal_main"][self.color][pos])

        self.scores["切队奶盾"] = self.get_heal_swap()
        self.scores["切队奶盾"] = max(self.scores["切队奶盾"], 0)
        for pos in [1]:
            self.scores["切队奶盾"] += 0.1 * (self.get_heal_swap() - global_stat["heal_main"][self.color][pos])

        heal_back = (self.heal["上级"]["back"] + self.heal["上级+"]["back"]) / 2
        self.scores["后排奶盾"] = (heal_back ** 0.5 - 4.5) * 9
        for pos in [3]:
            if heal_back < global_stat["heal_back"][pos]:
                self.scores["后排奶盾"] += 0.25 * (heal_back ** 0.5 - global_stat["heal_back"][pos] ** 0.5) * 9
        self.scores["后排奶盾"] = max(self.scores["后排奶盾"], 0)
        #self.scores["后排奶盾"] = heal_back

        if self.color == "粉":
            self.scores["前排奶盾"] -= 1
            self.scores["切队奶盾"] += 2
        if self.color == "绿":
            # angelic angel
            if self.card_type == "sk":
                self.scores["前排奶盾"] += 2
            # 大扑棱蛾子
            if self.is_aqours:
                self.scores["前排奶盾"] += 2
                self.scores["切队奶盾"] += 1
        if self.color == "蓝":
            # 六单
            self.scores["前排奶盾"] += 3
            if self.card_type == "gd":
                self.scores["前排奶盾"] += 1
        if self.color == "黄":
            # 君辉
            if self.card_type == "sk":
                self.scores["前排奶盾"] += 1
                self.scores["切队奶盾"] += 1
        if self.color == "红":
            # 君辉
            if self.card_type == "sk":
                self.scores["前排奶盾"] += 2
            if self.card_type == "gd":
                self.scores["切队奶盾"] += 1
        
        # 后排爆分
        support_magical = 0.
        self.scores["通用后排爆分"] = self.get_support_scoring_all(support_all)
        self.scores["同属性后排爆分"] = self.get_support_scoring_same_attribute(support_same_attribute)
        #if self.name in ["p果", "p绘", "p彼"]:
        #    print(self.name , self.active_2_support_magical, self.active_2_support_magical_same_attribute, support_all, support_same_attribute, support_magical, support_magical_same_attribute, )

        # 减伤
        self.scores["减伤"] = 0
        
        if len(self.skills) == 1 and self.skills[0]["type"] == "减伤":
            self.scores["减伤"] = 30
            if self.name in ["萝卜丸", "1姬", "赌场爱"]:
                self.scores["减伤"] = 40
            if self.name in ["夏日丸"]:
                self.scores["减伤"] = 50
            self.scores["减伤"] += 2 * (self.heal_swap_one_time ** 0.5 - 5)
        if self.name in ["蒸汽千"]:
            self.scores["减伤"] = 40
        if self.name in ["2花"]:
            self.scores["减伤"] = 45

        # 0曜
        if self.name in ["兔子曜"]:
            self.scores["千伤回血"] = 75

        # 同学校辅助爆分
        if self.name in ["应援果", "鬼神希"]:
            self.scores["同学校后排辅助爆分"] = 50

        # 驱散
        if self.actives[0]["type"] == "驱散":
            if self.actives[0]["trigger"] == "SP发动时":
                self.scores["驱散"] = 50
            elif self.actives[0]["trigger"] == "切队时":
                if self.actives[0]["trigger_rate"] == 0.3:
                    self.scores["驱散"] = 40
                elif self.actives[0]["trigger_rate"] == 0.2:
                    self.scores["驱散"] = 30

        # SBL抢赏
        if self.card_type == "sk":
            if self.skills[0]["type"] in ["快充", "st奶", "te奶"]:
                self.scores["SBL抢赏"] = 40
        if self.name in ["羊驼花"]:
            self.scores["SBL抢赏"] = 42
        elif self.name in ["1曜"]:
            self.scores["SBL抢赏"] = 45

        # 超充
        if self.actives[0]["type"] == "超充":
            self.scores["超充"] = 50

        # 得到总分和定位
        self.max_score = 0.
        self.max_k = ""
        self.final_score = 0.
        combine = 8
        for k in self.scores.keys():
            if self.scores[k] > 0:
                self.final_score += self.scores[k] ** combine
            if self.scores[k] > self.max_score:
                self.max_k = k
                self.max_score = self.scores[k]
        self.final_score = self.final_score ** (1/combine)

        # 得到主要定位和合宿选择
        best_inspirations = {
            "上级输出": ["红值同作战", "红值同属性"],
            "上级+输出": ["红值同作战", "红值同属性"],
            "前排奶盾": ["红值同作战", "红值同属性"],
            "通用后排辅助": ["红值仲间"],
            "通用后排爆分": ["红值仲间"],
            "同属性后排辅助": ["红值同属性", "红值仲间"],
            "同属性后排爆分": ["红值同属性", "红值仲间"],
            "后排奶盾": ["红值仲间"],
            "减伤": ["红值仲间"],
            "驱散": ["红值仲间"],
            "切队奶盾": ["红值同属性", "红值仲间"],
            "千伤回血": ["红值仲间"],
            "SBL抢赏": ["特技仲间"],
            "同学校后排辅助爆分": ["红值同学校", "红值仲间"],
            "超充": ["红值同属性"]
        }
        

        # 找到最强定位和可用定位列表
        self.valid_positions = []
        for k in self.scores.keys():
            if self.max_score - self.scores[k] < 20. and self.scores[k] > 30.:
                self.valid_positions.append(k)
        # 确定合宿
        self.best_inspirations = []
        self.valid_inspirations = {}
        self.nagamas = []
        self.diff_inspirations = False
        if self.max_k != "":
            for p in self.valid_positions:
                if best_inspirations[p] == ["红值仲间"]:
                    self.nagamas.append(p)
                if best_inspirations[p] != best_inspirations[self.max_k]:
                    self.diff_inspirations = True
                for inspiration in best_inspirations[p]:
                    if inspiration in self.valid_inspirations.keys():
                        self.valid_inspirations[inspiration] += 1.5 if p == self.max_k else 1
                    else:
                        self.valid_inspirations[inspiration] = 1.5 if p == self.max_k else 1
            best_found = False
            if self.name in ["p千", "花园艾"]:
                print(self.name, self.nagamas, self.scores["通用后排辅助"])
            if not self.diff_inspirations and self.scores[self.max_k] > 30.:
                self.best_inspirations = best_inspirations[self.max_k]
            else:
                for p in self.valid_positions:
                    if best_inspirations[p] == ["红值仲间"] or p == "同学校后排辅助爆分": #同学校后排辅助爆分 是写死的，有逻辑了可以改掉
                        if self.nagamas == ["通用后排辅助"]:
                            if self.scores["通用后排辅助"] >= 70.:
                                self.best_inspirations = ["红值仲间"]
                                best_found = True
                        else:
                            self.best_inspirations = ["红值仲间"]
                            best_found = True
                if not best_found:
                    best_poll = 0
                    for inspiration in self.valid_inspirations.keys():
                        if best_poll < self.valid_inspirations[inspiration]:
                            best_poll = self.valid_inspirations[inspiration]
                    for inspiration in self.valid_inspirations.keys():
                        if best_poll == self.valid_inspirations[inspiration]:
                            self.best_inspirations.append(inspiration)


    def calculate_type(self, team):
        if self.card_type == "vo":
            self.attack += 0.05 * team.total_attack
            self.attack += 0.05 * team.skill_magical_vog
        elif self.card_type == "sp":
            self.magical += 0.0015 * team.sp_score / 3
            self.magical += 0.05 * team.skill_magical_sp
            self.magical -= team.sp_type_debuff * team.skill_magical
            self.attack += 0.1 * 0.0015 * team.total_attack
            self.attack -= team.sp_type_debuff * team.skill_physical
        elif self.card_type == "gd":
            self.magical -= team.gd_type_debuff * 0.03 * team.sp_score / 3
            self.attack -= 0.1 * team.gd_type_debuff * 0.03 * team.total_attack
        elif self.card_type == "sk":
            self.attack -= team.sk_type_debuff * team.total_attack
            self.magical += 0.05 * team.skill_magical
            self.attack += 0.05 * team.skill_physical
        else:
            print("unknown type:", self.name, self.card_type)

    def calculate_skill(self, skill, team, song, is_skill=False, scope_multiplier=1., trigger_rate=1.):
        
        skill_trigger_multiplier = team.skill_trigger_bonus if is_skill else 1.
        skill_effect = skill["effect"]
        back_effective = False
        have_support = False
        have_support_diff_attribute = True
        heal_swap = False
        magical = 0.
        magical_diff_attribute = 0.
        
        try:
            skill_effect *= scope_multiplier
            if self.attack != "ap爆分":
                skill_effect *= trigger_rate
        except:
            pass
        num_triggers = None
        num_triggers_max = None
        sp_value = 0. # 几个sp
        num_sps = int(team.total_notes / team.sp_average_note) + team.sp_from_acs
        # 一次性收益类型的个2，触发几次
        #if self.name == "警察鸟":
        #    print(skill)
        #if is_skill and trigger_rate != 1:
        #    num_triggers = trigger_rate * team.total_notes
        if "trigger" in skill.keys():
            if skill["trigger"] == "自身表现时" and skill["notes"] == 0:
                num_triggers = trigger_rate * team.total_notes / 3
            if skill["trigger"] == "自身暴击时" and skill["notes"] == 0:
                num_triggers = trigger_rate * team.total_notes / 3 * self.critical_rate
            if skill["trigger"] == "歌曲开始时":
                num_triggers = trigger_rate
            if skill["trigger"] == "20次":
                num_triggers = 20
            if skill["trigger"] == "SP20次":
                num_triggers = team.total_notes / team.sp_average_note + team.sp_from_acs
                num_triggers = min(20, num_triggers)
            if num_triggers and "limit" in skill.keys() and skill["limit"] > 0:
                num_triggers = min(num_triggers, skill["limit"])
            if skill["type"] in ["ap", "特殊ap", "vo", "apup", "暴击率", "暴伤", "特技", "慢充", "ap每vo"] and skill["notes"] > 0:
                if skill["trigger"] == "切队时":
                    have_support = True
                    num_triggers = 1. * skill["notes"] / team.total_notes
                    num_triggers_max = num_triggers / trigger_rate
                elif skill["trigger"] == "AC开始时" or skill["trigger"] == "AC完成时":
                    have_support = True
                    num_triggers = team.num_acs * skill["notes"] / team.total_notes * trigger_rate
                    num_triggers_max = num_triggers * (0.5 + 0.5 * trigger_rate) / trigger_rate
                elif skill["trigger"] == "自身表现时":
                    num_triggers = skill["notes"] / 3
                elif skill["trigger"] == "自身暴击时":
                    num_triggers = skill["notes"] / 3 * self.critical_rate
                elif skill["trigger"] == "歌曲开始时":
                    num_triggers = skill["notes"] / team.total_notes
                elif skill["trigger"] == "受到200以上伤害时":
                    num_triggers = skill["notes"]
                elif skill["trigger"] == "SP发动时":
                    have_support = True
                    num_triggers = num_sps
                    if skill["limit"] > 0:
                        num_triggers = min(num_triggers, skill["limit"])
                    num_triggers *= skill["notes"] / team.total_notes
                    # 需要考虑SP发动容易溢出的问题
                    if skill["type"] in ["ap", "vo", "apup", "暴伤"]:
                        if skill["notes"] > 10:
                            num_triggers *= 0.75
                        else:
                            num_triggers *= 0.55
                    num_triggers_max = num_triggers * (0.5 + 0.5 * trigger_rate) / trigger_rate
                else:
                    print("warning no trigger:", self.name, skill["trigger"])
                if skill["scope"] not in ["全员", "同属性", "仲间"]:
                    have_support = False
                if skill["scope"] != "全员":
                    have_support_diff_attribute = False
            # 持续全程的，要算等效触发次数
            elif skill["type"] in ["ap", "特殊ap", "vo", "apup", "暴击率", "暴伤", "特技", "慢充"] and skill["notes"] == 0:
                have_support = True
                if skill["trigger"] == "歌曲全程":
                    num_triggers = 1
                    num_triggers_max = num_triggers / trigger_rate
                elif skill["trigger"] == "AC中":
                    num_triggers = 0.4
                    num_triggers_max = num_triggers * (0.5 + 0.5 * trigger_rate) / trigger_rate
                elif skill["trigger"] in ["AC开始时", "AC完成时"]:
                    if skill["limit"] == 1:
                        num_triggers = 0
                        num_triggers_max = 2*team.num_acs / (2*team.num_acs+1) / trigger_rate
                        no_trigger_prob = 1.
                        # skill_effect /= trigger_rate
                        for count_ac in range(team.num_acs):
                            num_triggers += (2*team.num_acs-2*count_ac) / (2*team.num_acs+1) * no_trigger_prob
                            no_trigger_prob *= (1-trigger_rate)
                        
                    else:
                        num_triggers = 0
                        num_triggers_max = 0.4 * (0.5 + 0.5 * trigger_rate) / trigger_rate 
                        for count_ac in range(team.num_acs):
                            num_triggers += (2*team.num_acs-2*count_ac) / (2*team.num_acs+1)
                elif skill["trigger"] == "SP发动时":
                    if skill["limit"] == 1:
                        num_triggers = 0
                        num_triggers_max = (num_sps - 1) / num_sps / trigger_rate
                        no_trigger_prob = 1.
                        for count_sp in range(num_sps):
                            num_triggers += (num_sps - count_sp - 1) / (num_sps) * no_trigger_prob
                            no_trigger_prob *= (1-trigger_rate)
                    else:
                        num_triggers = 0
                        
                        for count_sp in range(num_sps):
                            num_triggers += (num_sps - count_sp - 1) / (num_sps)
                        num_triggers_max = num_triggers * (0.5 + 0.5 * trigger_rate) / trigger_rate
                else:
                    print("warning no trigger:", self.name, skill["trigger"])
                if skill["scope"] not in ["全员", "同属性", "仲间"]:
                    have_support = False
                if skill["scope"] != "全员":
                    have_support_diff_attribute = False
            elif skill["trigger"] == "80%血量以下时":
                have_support = True
                num_triggers = 3
                if skill["limit"] > 0:
                    num_triggers = min(num_triggers, skill["limit"])
            elif skill["trigger"] == "SP发动时":
                have_support = True
                num_triggers = num_sps * trigger_rate
                if skill["limit"] > 0:
                    num_triggers = min(num_triggers, skill["limit"])
            elif skill["trigger"] == "AC开始时" or skill["trigger"] == "AC完成时":
                have_support = True
                num_triggers = team.num_acs * trigger_rate
                if skill["limit"] > 0:
                    num_triggers = min(num_triggers, skill["limit"])
                if skill["trigger"] == "AC完成时" and skill["type"] in ["ap快充"]:
                    num_triggers = 0
            elif skill["trigger"] == "切队时":
                if not "奶" in skill["type"] and not "盾" in skill["type"]:
                    num_triggers = 2
                    have_support = True   
            elif skill["trigger"][0:2] == "受到" and skill["trigger"][-5:] == "以上伤害时":
                have_support = True
                damage_cap = int(skill["trigger"][2:-5])
                if damage_cap <= 500:
                    num_triggers = team.total_notes * 0.6 * trigger_rate
                if skill["limit"] > 0:
                    num_triggers = min(num_triggers, skill["limit"])

        skip_skill = ["减伤", "复活"]
        if skill["type"] == "特技":
            if num_triggers:
                if skill["trigger"] == "SP发动时":
                    num_triggers *= 1.1
                magical += num_triggers * skill_effect * team.skill_magical / 0.33 * scope_multiplier * team.sp_cycle
                self.attack += num_triggers * skill_effect * team.skill_physical / 0.33 * scope_multiplier * team.sp_cycle
            else:
                magical += self.skill_notes * skill["effect"] / 9 * team.skill_magical / 0.33 * scope_multiplier * team.sp_cycle
                self.attack += self.skill_notes * skill["effect"] / 9 * team.skill_physical / 0.33 * scope_multiplier * team.sp_cycle
                #skill_attack = skill["effect"] * team.total_attack
                #if self.skill_notes > 0:
                #    skill_attack *= trigger_rate * self.skill_notes / 3
                #self.attack += skill_attack
        elif skill["type"] == "vo" or skill["type"] == "特殊ap" or skill["type"] == "apup":
            if num_triggers:
                self.attack += num_triggers * skill_effect * team.total_attack
                if have_support and skill["scope"] in ["全员", "同属性"]:
                    self.active_2_support_average = num_triggers * skill_effect
                    self.active_2_support_max = num_triggers_max * skill_effect
            else:
                skill_attack = skill["effect"]  * scope_multiplier * team.total_attack
                if self.skill_notes > 0:
                    skill_attack *= trigger_rate * self.skill_notes / 3
                self.attack += skill_attack
        elif skill["type"] in ["ap", "ap每vo"]:
            if skill["type"] in ["ap每vo"]:
                num_triggers *= 4
            if num_triggers:
                self.attack += num_triggers * skill_effect * team.total_attack / team.active_ap_multiplier
                if have_support and skill["scope"] in ["全员", "同属性"]:
                    self.active_2_support_average = num_triggers * skill_effect / team.active_ap_multiplier
                    self.active_2_support_max = num_triggers_max * skill_effect / team.active_ap_multiplier
            else:
                skill_attack = skill["effect"] * scope_multiplier * team.total_attack / team.active_ap_multiplier * skill_trigger_multiplier
                if self.skill_notes > 0:
                    skill_attack *= trigger_rate * self.skill_notes / 3
                self.attack += skill_attack
        elif skill["type"] == "ap爆分":
            vog_multiplier = 0.
            for ap in team.appeal_multipliers.keys():
                vog_multiplier += ap / 1.23 * team.appeal_multipliers[ap]
            if num_triggers:
                magical += skill["effect"] * num_triggers / team.total_notes * self.final_ap * vog_multiplier * 3
                magical_diff_attribute += magical
            elif trigger_rate != 1.:
                for ap in team.appeal_multipliers.keys():
                    scoring = min(skill_effect * self.final_ap * ap / 1.23 * team.same_attribute_multiplier, team.vog_limit)
                    magical += scoring * team.appeal_multipliers[ap] * trigger_rate * skill_trigger_multiplier * 3
            else:
                magical += skill["effect"] * self.final_ap * team.active_ap_multiplier * vog_multiplier * team.same_attribute_multiplier * 0.33
        elif skill["type"] == "te爆分":
            if num_triggers:
                magical += skill["effect"] * num_triggers / team.total_notes * self.real_te * team.same_attribute_multiplier * 3
                magical_diff_attribute += magical / team.same_attribute_multiplier
            else:
                magical += skill["effect"] * self.real_te * team.same_attribute_multiplier * 0.33 * skill_trigger_multiplier
        elif skill["type"] == "核爆":
            if team.difficulty == "上级+" and team.sp_score < 500000:
                magical += skill["effect"] * self.final_ap * team.active_ap_multiplier * team.vog_multiplier * team.same_attribute_multiplier * 0.33 * skill_trigger_multiplier
        elif skill["type"] == "ap核爆":
            if num_triggers:
                if team.difficulty == "上级+" and team.sp_score < 500000:
                    magical += num_triggers * skill["effect"] * self.final_ap * team.active_ap_multiplier * team.vog_multiplier * team.same_attribute_multiplier * 3 / team.total_notes
            else:
                if team.difficulty == "上级+" and team.sp_score < 500000:
                    magical += skill_effect * self.final_ap * team.active_ap_multiplier * team.vog_multiplier * team.same_attribute_multiplier * skill_trigger_multiplier
        elif skill["type"] == "te核爆":
            if num_triggers:
                if team.difficulty == "上级+" and team.sp_score < 500000:
                    magical += num_triggers * skill["effect"] * self.real_te * team.same_attribute_multiplier * 3 / team.total_notes
                    magical_diff_attribute += magical / team.same_attribute_multiplier
            else:
                if team.difficulty == "上级+" and team.sp_score < 500000:
                    magical += skill_effect * self.real_te * team.same_attribute_multiplier * skill_trigger_multiplier
        # 所有充电相关的计算
        elif skill["type"] == "快充":
            if trigger_rate == 1.:
                skill_effect *= 0.33
            # 分为两部分：一部分是sp得分，另一部分是sp时间加成和警察鸟的个性2
            if num_triggers:
                sp_value = skill["effect"] * num_triggers
            else:
                sp_value = skill_effect * team.total_notes / 3 * skill_trigger_multiplier
        elif skill["type"] == "ap快充":
            if num_triggers:
                sp_value = skill_effect * self.final_ap * num_triggers / team.sp_gauge
        elif skill["type"] == "te快充":
            if num_triggers:
                sp_value = skill_effect * self.real_te * num_triggers / team.sp_gauge
        elif skill["type"] == "sp获得":
            sp_value = num_triggers * skill_effect / team.sp_gauge
        elif skill["type"] == "慢充":
            if num_triggers:
                sp_value = skill_effect * num_triggers * 217 / team.sp_gauge * team.total_notes
            else:
                sp_value = skill_effect * self.skill_notes * 217 / team.sp_gauge * team.total_notes / 3 * skill_trigger_multiplier
        # 所有充电相关的计算结束
        elif skill["type"] == "暴击率":
            if num_triggers:
                self.teammate_crit_bonus += skill_effect * num_triggers * scope_multiplier
            elif self.skill_notes > 0:
                note = int((self.skill_notes + 2) / 3)
                max_crit_bonus = 1 - self.teammate_critical_rate - self.teammate_crit_bonus
                self.teammate_crit_bonus += 1. * min(skill["effect"], max_crit_bonus) * note * 0.33 * skill_trigger_multiplier * scope_multiplier
            elif "/" in str(skill["effect"]):
                effect, note = str(skill["effect"]).split("/")
                effect = float(effect.replace("%", "")) / 100.
                note = int((int(note) + 2) / 3)
                max_crit_bonus = 1 - self.teammate_critical_rate - self.teammate_crit_bonus
                self.teammate_crit_bonus += 1. * min(effect, max_crit_bonus) * note * 0.33 * skill_trigger_multiplier
            else:
                self.teammate_crit_bonus += skill["effect"]
        elif skill["type"] == "暴伤":
            if num_triggers:
                self.attack += num_triggers * skill_effect * team.total_attack / team.base_critical_damage
                if have_support and skill["scope"] in ["全员", "同属性"]:
                    self.active_2_support_average = num_triggers * skill_effect / team.base_critical_damage
                    self.active_2_support_max = num_triggers_max * skill_effect / team.base_critical_damage
            else:
                skill_attack = skill["effect"] * team.total_attack / team.base_critical_damage * skill_trigger_multiplier
                if self.skill_notes > 0:
                    skill_attack *= trigger_rate * self.skill_notes / 3
                self.attack += skill_attack
        elif skill["type"] == "超限":
            self.score_limit += team.score_limit * skill["effect"]
        elif skill["type"] == "st奶" or skill["type"] == "st盾" or skill["type"] == "te奶" or skill["type"] == "te盾":
            base = self.final_st if "st" in skill["type"] else self.real_te
            if num_triggers:
                heal_tmp = num_triggers * skill["effect"] * base / team.total_notes
                self.heal_main += heal_tmp
                if have_support or heal_swap:
                    self.heal_swap_one_time += heal_tmp
                if have_support:
                    # 后排要考虑饰品少te
                    self.heal_back += num_triggers * skill["effect"] * (base - (370 if "te" in skill["type"] else 0)) / team.total_notes / team.same_attribute_multiplier
                    if self.name in ["花园绘", "珠宝鸟"]: #先写死，100%的因为上限低要少算
                        self.heal_back *= 0.8
            else:
                if "trigger" in skill.keys() and skill["trigger"] == "切队时":
                    if skill["limit"] <= 0:
                        self.heal_swap += skill["effect"] * trigger_rate * base * 2 / team.total_notes
                    else:
                        self.heal_swap_one_time += skill["effect"] * min(6, skill["limit"]) * trigger_rate * base / team.total_notes
                elif is_skill:
                    self.heal_main += skill["effect"] * base * trigger_rate / 3
                    self.heal_swap += skill["effect"] * base * 2 / team.total_notes / (1.5 if trigger_rate == 0.11 else 1)
                    if self.card_type == "gd":
                        self.heal_swap += 0.05 * base / team.total_notes
        elif skill["type"] == "st奶每gd":
            if num_triggers:
                heal_tmp = num_triggers * skill["effect"] / team.total_notes
                self.heal_main += heal_tmp
                if have_support or heal_swap:
                    self.heal_swap_one_time += heal_tmp
                if have_support:
                    # 后排要考虑饰品少te
                    self.heal_back += num_triggers * skill["effect"] / team.total_notes / team.same_attribute_multiplier
        elif skill["type"] in skip_skill:
            pass
        else:
            #print("unknown skill:", self.name, skill["type"])
            pass

        # 充电最终计算
        magical += (sp_value * team.sp_type_time_bonus * team.sp_cycle) / team.total_notes * team.sp_score * 3
        self.attack += 0.15 * (sp_value * 9 * team.sp_type_time_bonus * team.sp_cycle) / team.total_notes * team.total_attack 

        self.magical += magical
        
        if have_support:
            if have_support_diff_attribute:
                self.active_2_support_magical += magical_diff_attribute
                self.active_2_support_magical_same_attribute += magical
            else:
                self.active_2_support_magical_same_attribute += magical
        

    def calculate_support(self, team):
        support_all = self.slot * 0.01
        support_same_attribute = self.slot * 0.01
        # 个性1，由于现在满爆卡强势，黄值拐的价值要低一些
        active_1_support = self.passive_ap * 0.5 + self.passive_te * 0.3
        if self.passive_scope in ["全员", "仲间"]:
            support_all += active_1_support
            support_same_attribute += active_1_support
        elif self.passive_scope == "同属性":
            support_same_attribute += active_1_support
        # 个性2
        self.support_all_average = support_all
        self.support_same_attribute_average = support_same_attribute
        self.support_all_max = support_all
        self.support_same_attribute_max = support_same_attribute
        if self.actives[0]["scope"] in ["全员", "仲间"]:
            self.support_all_average += self.active_2_support_average
            self.support_same_attribute_average += self.active_2_support_average
            self.support_all_max += self.active_2_support_max
            self.support_same_attribute_max += self.active_2_support_max
        elif self.actives[0]["scope"] == "同属性":
            self.support_same_attribute_average = support_same_attribute + self.active_2_support_average
            self.support_same_attribute_max = support_same_attribute + self.active_2_support_max
        # 直接得分
        magical_base = 400000
        self.support_all_average += self.active_2_support_magical / magical_base
        self.support_all_max += self.active_2_support_magical / magical_base
        self.support_same_attribute_average += self.active_2_support_magical_same_attribute / magical_base
        self.support_same_attribute_max += self.active_2_support_magical_same_attribute / magical_base

    def get_heal_main(self):
        damage_for_heal = 0.5 * self.power["上级+"]["average"] + 0.5 * self.power["上级"]["average"]
        score_heal_main = (damage_for_heal - 60000) / 1500 
        heal_main = (self.heal["上级"]["main"] + self.heal["上级+"]["main"]) / 2

        if heal_main < 500:
            score_heal_main -= (500 - heal_main) / 5
        else:
            score_heal_main += (heal_main ** 0.5 - 500 ** 0.5)
        return score_heal_main

    def get_heal_swap(self):
        support_same_attribute = (self.support["上级"]["same_attribute"] + self.support["上级+"]["same_attribute"] + self.support["上级"]["same_attribute_max"] + self.support["上级+"]["same_attribute_max"]) / 4
        damage_for_heal = 0.5 * self.power["上级+"]["average"] + 0.5 * self.power["上级"]["average"]

        heal_damage_reduction = 0.
        if self.name == "2花":
            heal_damage_reduction = 15000 * 0.3 * 3 / 300
        if self.name == "蒸汽千":
            heal_damage_reduction = 20000 * 0.44 * 1.5 / 300
        if self.heal_swap > 0:
            reward_heal_swap = 40000000 * support_same_attribute
            damage_need_heal = 300 - self.heal_swap_one_time - heal_damage_reduction
            num_swaps = damage_need_heal / self.heal_swap
            reward_heal_swap -= (1250000 - 2 * (damage_for_heal)) * num_swaps
            return (reward_heal_swap + 8000000) / 110000
        else:
            return 0

    def get_support_all(self):
        return (self.support["上级"]["all"] + self.support["上级+"]["all"] + self.support["上级"]["all_max"] + self.support["上级+"]["all_max"]) / 4

    def get_support_same_attribute(self):
        return (self.support["上级"]["same_attribute"] + self.support["上级+"]["same_attribute"] + self.support["上级"]["same_attribute_max"] + self.support["上级+"]["same_attribute_max"]) / 4

    def get_support_scoring_all(self, support_all):
        result = 0
        if self.active_2_support_magical > 1000:
            support_magical = 40000 * support_all + self.active_2_support_magical
            if self.passive_scope == "全员": # 注：计算爆分时te辅助的作用更小，因为上级一般用的都是满爆卡
                support_magical -= 40000 * 0.05 * self.passive_te
            result = (support_magical - 1000) / 50 
        return result

    def get_support_scoring_same_attribute(self, support_same_attribute):
        result = 0
        if self.active_2_support_magical_same_attribute > 1000:
            support_magical_same_attribute = 40000 * support_same_attribute + self.active_2_support_magical_same_attribute
            if self.passive_scope in ["全员", "同属性"]: # 注：计算爆分时te辅助的作用更小，因为上级一般用的都是满爆卡
                support_magical_same_attribute -= 40000 * 0.15 * self.passive_te
            result = (support_magical_same_attribute - 2000) / 50
        return result